package com.example.a10.controller;

import cn.hutool.extra.servlet.ServletUtil;
import com.example.a10.server.JsonServer;
import com.example.a10.util.AddressConstants;
import com.example.a10.entity.Document;
import com.example.a10.entity.PredictDocument;
import com.example.a10.python.PythonProcedure;
import com.example.a10.util.DocumentUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/Model")
public class ModelController {

    @Autowired
    PythonProcedure pythonProcedure;
    @Autowired
    HttpServletResponse response;
    @Autowired
    JsonServer jsonServer;

    @ApiOperation("接受训练数据文件名称,训练模型")
    @PostMapping( "/Train")
    public String TrainModel(@RequestBody Document document){
        String TrainName = document.getName();
        int train = -1;
        if (TrainName!=null){
            train = pythonProcedure.Train(TrainName);
            if (train==0){
                return "success";
            }
        }
        return "failed";
    }

    @ApiOperation("接受测试数据文件名称和模型文件的名称，预测数据")
    @PostMapping("/Predit")
    public String PreditModel(@RequestBody PredictDocument predictDocument){
        String modelName = predictDocument.getModelName();
        String TestName = predictDocument.getTestName();
        int predict = -1;
        if (modelName!=null && TestName!=null){
            predict = pythonProcedure.Predict(modelName, TestName);
            if(predict==0){
                return "success";
            }
        }
        return "failed";
    }

    @ApiOperation("预测多个数据")
    @PostMapping("/PreditMulti")
    public String PreditMultiModel(@RequestBody Map<String, Object> requestBody){
        String modelname = (String)requestBody.get("modelname");
        String[] testnames = ((List<String>)requestBody.get("testnames")).toArray(new String[0]);
        int predict = -1;
        for (int i = 0; i < testnames.length; i++) {
            String testname=testnames[i];
            predict = pythonProcedure.Predict(modelname, testname);
            if(predict!=0){
                return "failed";
            }
        }
        if(predict==0){
            return "success";
        }else {
            return "failed";
        }
    }

    @ApiOperation("接受模型文件的名称,下载模型")
    @PostMapping("/download")
    public void Download(@RequestBody Document document){
        String fileName = document.getName();
        File file = new File(AddressConstants.Model + fileName);
        //防止中文乱码
        response.setCharacterEncoding("UTF-8");
        ServletUtil.write(response,new File(AddressConstants.Model+fileName));
    }

    @ApiOperation("返回所有模型文件的名称")
    @GetMapping("/list")
    public List<Document> list(){
        File file = new File(AddressConstants.Model);
        String[] Trainlist = file.list();
        List<Document> documents = new ArrayList<>();
        for (String train:Trainlist){
            Document document = new Document();
            document.setName(train);
            String filesize = DocumentUtil.getFilesize(AddressConstants.Model + train);
            document.setSize(filesize);
            documents.add(document);
        }
        return documents;
    }

    @ApiOperation("返回模型文件名称，删除模型")
    @DeleteMapping("/delete")
    public String deleteModel(@RequestBody Document document){
        if(document!=null){
            String name = document.getName();
            String featureName = name.replace(".txt", ".json");
            File file = new File(AddressConstants.Model+name);
            File featurefile = new File(AddressConstants.Feature+featureName);
            file.delete();
            featurefile.delete();
            return "success";
        }else {
            return "failed";
        }
    }

    @ApiOperation("获取模型特征重要性数据，返回排名前10的数据")
    @PostMapping("/FeatureImport")
    public List<Map.Entry<String, Integer>> FeatureData(@RequestBody Document document) throws IOException {
        String modelname=document.getName();
        String featureName = modelname.replace(".txt", ".json");
        File file = new File(AddressConstants.Feature + featureName); // 创建文件对象
        boolean exists = file.exists();
        //如果不存在，则调用python生成
        if(exists==false){
           pythonProcedure.Feature(modelname);
        } else{
            Map<String, Object> stringObjectMap = jsonServer.readfeatureJsonFile(featureName);
            Map<String, Integer> data = new HashMap<>();
            for (Map.Entry<String, Object> entry : stringObjectMap.entrySet()) {  // 遍历 Map，将数据类型转换为 Integer
                data.put(entry.getKey(), Integer.valueOf(entry.getValue().toString()));
            }
            // 对Map数据进行排序
            List<Map.Entry<String, Integer>> list = new ArrayList<>(data.entrySet());
            Collections.sort(list, Map.Entry.comparingByValue(Comparator.reverseOrder()));

            // 取出前十个最高的数据
            List<Map.Entry<String, Integer>> topTen = list.subList(0, Math.min(10, list.size()));
            return topTen;
        }
        return null;
    }

}
